#include<iostream>
#include<signal.h>
#include<unistd.h>
#include<cassert>
#include<sys/wait.h>
void Printgsig(sigset_t &pending)
{
   std::cout<<"pending bitmap ";
   for (int signo = 31; signo < 0; signo--)
   {
       if(sigismember(&pending,signo))
       {
            std::cout<<"1";
       }
       else
       {
            std::cout<<"0";
       }
   }
   std::cout<<std::endl;
}
void handnler(int  signo)
{
    sigset_t pending;
    sigemptyset(&pending);
    int n = sigpending(&pending);
    assert(n==0);
    std::cout<<"递达中...:";
    Printgsig(pending);
}
int main()
{
    //对2好信号进行自定义捕捉--不让进程因2号信号而终止
    signal(2,handnler);

    //屏蔽2信号；
    sigset_t block,oblock;
    sigemptyset(&block);
    sigemptyset(&oblock);
    sigaddset(&block,2);//在运行的时候根本就没有设置在进程的pcb block位图当中
    //如果屏蔽做所有信号
    for(int signo = 1;signo<=31;signo++)
    {
        sigaddset(&block,signo);
        //9 19号信号无法被屏蔽，18号信号hi被左页数处理
        //SIGINT本很就没有设置进当前进程的pcb block位图中
    }
    //开始屏蔽2信号，其实就是设置进入内核中
    int n =sigprocmask(SIG_SETMASK,&block,&oblock);
    assert(n==0);
    (void)n;//骗过编译器，不要警告，
    std::cout<<"block 2 signal, sucess"<<std::endl;
    std::cout<<"pid"<<getpid()<<std::endl;
    int cnt = 0;
    while (true)
    {
        //2获取进程pending位图
        sigset_t pending;
        sigemptyset(&pending);
        n = sigpending(&pending);
        assert(n==0);
        Printgsig(pending);//打印pending位图
        cnt++;
        //解除对2号信号的屏蔽
        if(cnt ==2)
        {
            std::cout<<"解除对2号信号屏蔽"<<std::endl;
            n = sigprocmask(SIG_UNBLOCK,&block,&oblock);
            assert(n==0);
        }
        sleep(1);
    }
    //有没有涉及到将数据设置进内核中？没有
    //sigset_t int double float class 没有差别
    //用户在栈上开辟了空间
    // sigset_t s;
    // sigemptyset(&s);
    // sigaddset(&s,2);
    // //创建子进程
    // pid_t id = fork();
    // if(id == 0)
    // {
    //     sleep(2);
    //     int a = 10;
    //     a/=0;//收到信号->SIGFPE->core
    //     exit(0);
    // }
    // int status = 0;
    // pid_t rid = waitpid(id,&status,0);
    // if(rid ==0)
    // {
    //     std::cout<<"exit code:"<<((status>>8)&0xFF)<<std::endl;
    //     std::cout<<"exit signal:"<<(status &0x7F)<<std::endl;
    //     std::cout<<"exit code:"<<((status>>7)&0x1)<<std::endl;
    // } 
    // std::cout<<"run begin ..."<<std::endl;
    // int a =10;
    // a/=0;
    // std::cout<<"run end ..."<<std::endl;
    // while (true)
    // {
    //     sleep(1);
    // }
    
    return 0;
}